# -*- coding: utf-8 -*-
import os, socket, math
import pygame
from pygame.locals import *

import settings, tuio, movie, OSC
from gameEngine import Scene

class NewsMachine(Scene):
    def __init__(self):
        self.flags = self.framerate = 0
        if settings.FULLSCREEN:
            self.flags = pygame.FULLSCREEN
        self.framerate = settings.FRAMERATE or 25
        
        Scene.__init__(self, settings.RESOLUTION, settings.BACKGROUND, self.flags, self.framerate)
        self.screen_size = self.width, self.height = settings.RESOLUTION
        
        self.square = pygame.Surface((settings.TRACKING_RECT))
        self.square.fill((settings.TRACKING_COLOR))
        self.background.blit(self.square, (0, settings.TRACKING_TOP))
        
        #self.help = pygame.image.load(settings.HELP_PATH)
        #self.help = self.help.convert()
        #self.background.blit(self.help, settings.HELP_POSITION)
        
        self.objectsprites = self.makeSpriteGroup([])
        self.labelsprites = self.makeSpriteGroup([])
        self.moviesprites = self.makeSpriteGroup([])
        
        self.addGroup(self.moviesprites)
        if settings.DRAW_SPRITES:
            #self.addGroup(self.objectsprites)
            self.addGroup(self.labelsprites)
        
        self.client = tuio.TuioClient(self, "/tuio/2Dobj", "/tuio/2Dcur")
        self.movieplayer = movie.MoviePlayer(self)
        self.current_movie = 0
        self.current_preview = 0
        self.playlist = []
        
        pygame.mouse.set_visible(False)
        self.setCaption(settings.CAPTION)
        self.start()
    
    def refresh(self):
        """
        running every cycle of eventloop, without an event object
        """
        pass
    
    def add_tuio_obj(self, s_id, f_id):
        """
        called when a new object was detected
        """
        self.objectsprites.add(tuio.TuioObject(self, s_id, f_id))
        self.labelsprites.add(tuio.TuioLabel(self, s_id, f_id))
    
    def update_tuio_obj(self, s_id, f_id, x, y, a, X, Y, A, m, r):
        """
        called when a TuioObject is updated
        """
        new_x = int(x*self.width)
        new_y = int(y*self.height)
        minimum_height = settings.TRACKING_TOP
        maximum_height = minimum_height+settings.TRACKING_HEIGHT
        # checks if the new position is between the allowed values
        if minimum_height <= new_y <= maximum_height:
            new_speed = math.sqrt(X*X+Y*Y)
            for obj in self.objectsprites:
                if obj.f_id == f_id and obj.s_id == s_id:
                    obj.refresh(new_x, new_y, a, new_speed, A, m, r)
                    if obj.increment:
                        self.current_f_id = obj.f_id
                        self.current_increment = obj.increment
                        pygame.event.post(pygame.event.Event(settings.PLAYPREVIEW))
            for label in self.labelsprites:
                if label.f_id == f_id and label.s_id == s_id:
                    label.refresh(new_x, new_y)
        else:
            for label in self.labelsprites:
                if label.f_id == f_id and label.s_id == s_id:
                    label.refresh(new_x-10000, new_y-10000)
    
    def remove_tuio_obj(self, s_id, f_id):
        """
        remove a TuioObject from sprite list, according to s_id und f_id
        """
        for obj in self.objectsprites:
            if obj.f_id == f_id and obj.s_id == s_id:
                self.objectsprites.remove(obj)
        for label in self.labelsprites:
            if label.f_id == f_id and label.s_id == s_id:
                self.labelsprites.remove(label)
    
    def doEvents(self, event):
        """
        gets executed recursively in a eventlist loop defined in the suporior
        Scene class, giving an event
        """
        if event.type == pygame.KEYDOWN:
            if event.key in (pygame.K_ESCAPE, pygame.K_q):
                self.keepGoing = False
            elif event.key == pygame.K_RETURN:
                self.playlist = self.sorted_objects()
                pygame.event.post(pygame.event.Event(settings.PLAYNEXT))
            elif event.key == pygame.K_n:
                self.movieplayer.load_files()
            # if event.key == pygame.K_f and event.mod & (KMOD_META|KMOD_CTRL):
            #     self.toggle_fullscreen()
                
        elif event.type == settings.PLAYNEXT:
            if self.current_movie < len(self.playlist):
                f_id = self.playlist[self.current_movie].f_id
                if f_id in settings.WORDS:
                    # self.movieplayer.play("full", f_id)
                    self.movieplayer.play("preview", f_id)
                    self.current_movie+=1
            else:
                self.current_movie = 0
                self.playlist = []
                pygame.time.set_timer(settings.PLAYNEXT, 0)
        
        elif event.type == settings.PLAYPREVIEW:
            if pygame.mixer.get_init() is not None:
                pygame.mixer.quit()
            f_id = self.current_f_id
            if f_id in settings.WORDS:
                increment = self.current_increment
                self.movieplayer.play("preview", f_id, increment)
                pygame.time.set_timer(settings.PLAYPREVIEW, 0)
    
    def update(self):
        """
        running on every game cycle, receives the OSC packages from TuioClient
        """
        try:
            self.client.manager.handle(self.client.socket.recv(1536))
        except socket.error:
            pass
    
    def toggle_fullscreen(self):
        """
        toggles between fullscreen and windowed mode
        """
        screen = pygame.display.get_surface()
        tmp = screen.convert()
        caption = pygame.display.get_caption()
        w,h = screen.get_width(),screen.get_height()
        flags = screen.get_flags()
        bits = screen.get_bitsize()
        pygame.display.quit()
        pygame.display.init()
        screen = pygame.display.set_mode((w,h),flags^FULLSCREEN,bits)
        screen.blit(tmp,(0,0))
        pygame.display.set_caption(*caption)
        pygame.key.set_mods(0)
        pygame.mouse.set_visible(False)
    
    def sorted_objects(self):
        """
        sorts TuioObjects in objectsprites by its x position
        """
        objs = self.objectsprites.sprites()
        return sorted(objs, key=lambda obj: obj.x)
    
    # def addTuioCur(self, s_id):
    #     if not self.cursor_list.has_key(s_id):
    #         self.cursor_list.put(s_id, [])
    #
    # def updateTuioCur(self, s_id, x, y, X, Y, m):
    #     self.point_list = self.cursor_list.get(s_id)
    #     point = Point(int(x*self.width),int(y*self.height))
    #     self.point_list.put(point)
    #     self.repaint()
    #
    # def removeTuioCur(self, s_id):
    #     self.cursor_list.remove(f_id)
    #     self.repaint()

if __name__=="__main__":
    game = NewsMachine()
